<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="../css/main.css" media="all" rel="stylesheet" type="text/css" />
<link href="../css/highlight.css" media="all" rel="stylesheet" type="text/css" />
<link href="../css/print.css" media="print" rel="stylesheet" type="text/css" />
<title>第4章 - ページの作り方の基本</title>
</head>

<body>
<div class="navigation">

<table width="100%">
<tr>
<td width="40%" align="left"><a href="03-Running-Symfony.html">前の章</a></td>
<td width="20%" align="center"><a href="index.html">ホーム</a></td>
<td width="40%" align="right"><a href="05-Configuring-Symfony.html">次の章</a></td>
</tr>
</table>
<hr/>
</div>

<div>
<a name="chapter.4.the.basics.of.page.creation" id="chapter.4.the.basics.of.page.creation"></a><h1>第4章 - ページの作り方の基本</h1>

<p>興味深いことに、プログラマが新しい言語もしくはフレームワークを学ぶとき、最初に学ぶチュートリアルは"Hello,world!"をスクリーンに表示させることです。人工知能の分野におけるあらゆる試みが今のところ貧弱な会話能力の結果で終わっていることをふまえると、コンピュータを世界全体に挨拶できる何かと考えるのは奇妙なことです。しかしながら、symfonyはほかのプログラムよりも愚かではなく、その証明として、symfonyで"Hello,<code>&lt;あなたのお名前&gt;</code>"と表示するページを作ることができます。</p>

<p>この章ではモジュールの作り方をお教えします。モジュール(module)とはページを分類する構造上の要素です。MVCパターンなので、アクションとテンプレートに分割されたページの作り方も学びます。リンクとフォームはWebの基本的なインタラクションです。これらをテンプレートに挿入してアクションで処理する方法を理解します。</p>

<div class="toc">
<dl>
<dt><a href="#creating.a.module.skeleton">4.1. モジュールのスケルトンを作成する</a></dt>
<dt><a href="#adding.a.page">4.2. ページを追加する</a></dt>
<dd><dl>
<dt><a href="#adding.an.action">4.2.1. アクションを追加する</a></dt>
<dt><a href="#adding.a.template">4.2.2. テンプレートを追加する</a></dt>
<dt><a href="#passing.information.from.the.action.to.the.template">4.2.3. テンプレートにアクションからの情報を渡す</a></dt>
</dl></dd>
<dt><a href="#linking.to.another.action">4.3. 別のアクションにリンクする</a></dt>
<dt><a href="#getting.information.from.the.request">4.4. リクエストから情報を入手する</a></dt>
<dt><a href="#summary">4.5. まとめ</a></dt>
</dl>
</div>
<a name="creating.a.module.skeleton" id="creating.a.module.skeleton"></a><h2>モジュールのスケルトンを作成する</h2>

<p>2章で説明したように、symfonyはページをモジュールに分類します。ページを作るまえに、モジュールを作成する必要があります。モジュールはsymfonyが認識できるファイル構造を持つ骨組みで最初は内容を持ちません。</p>

<p>symfonyコマンドはモジュールの作成作業を自動化します。アプリケーションの名前とモジュールの名前を引数として<code>generate:module</code>タスクを呼び出すことだけが必要です。前の章で作成した<code>frontend</code>アプリケーションに<code>content</code>モジュールを追加するには、つぎのコマンドを入力します:</p>

<pre><code>&gt; cd ~/myproject
&gt; php symfony generate:module frontend content

&gt;&gt; dir+      ~/myproject/apps/frontend/modules/content/actions
&gt;&gt; file+     ~/myproject/apps/frontend/modules/content/actions/actions.class.php
&gt;&gt; dir+      ~/myproject/apps/frontend/modules/content/templates
&gt;&gt; file+     ~/myproject/apps/frontend/modules/content/templates/indexSuccess.php
&gt;&gt; file+     ~/myproject/test/functional/frontend/contentActionsTest.php
&gt;&gt; tokens    ~/myproject/test/functional/frontend/contentActionsTest.php
&gt;&gt; tokens    ~/myproject/apps/frontend/modules/content/actions/actions.class.php
&gt;&gt; tokens    ~/myproject/apps/frontend/modules/content/templates/indexSuccess.php
</code></pre>

<p><code>actions/</code>と<code>templates/</code>ディレクトリは別にして、このコマンドは3つのファイルだけ作りました。<code>test/</code>フォルダーのなかに存在するファイルは機能テストに関係しますが、15章まで気にする必要はありません。<code>actions.class.php</code>(リスト4-1で示されている)は<code>default</code>モジュールの初期ページに転送(フォワード)します。<code>templates/indexSuccess.php</code>ファイルは空です。</p>

<p>リスト4-1 - 生成されたデフォルトのアクション(<code>actions/actions.class.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw2">class</span> contentActions <span class="kw2">extends</span> sfActions
<span class="br0">&#123;</span>
  <span class="kw2">public</span> <span class="kw2">function</span> executeIndex<span class="br0">&#40;</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">forward</span><span class="br0">&#40;</span><span class="st_h">'default'</span><span class="sy0">,</span> <span class="st_h">'module'</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre>

<blockquote class="note"><p>
  実際の<code>actions.class.php</code>ファイルを見ると、多くのコメントを含めて、これら数行よりも多くのものが見つかります。なぜならsymfonyはプロジェクトのドキュメントを作るためにPHP形式のコメントを使い、phpDocumentorツール(<a href="http://www.phpdoc.org/">http://www.phpdoc.org/</a>)と互換性のあるクラスファイルを用意することを推奨しているからです。</p>
</blockquote>

<p>新しいそれぞれのモジュールに対して、symfonyはデフォルトの<code>index</code>アクションを作ります。これは<code>executeIndex</code>と呼ばれるアクションメソッドと<code>indexSuccess.php</code>と呼ばれるテンプレートファイルから構成されます。プレフィックスの<code>execute</code>とサフィックスの<code>Success</code>の意味は6章と7章で説明します。それまでの間はこの命名方法を規約として考えることにします。つぎのURLをブラウザーに入力すると対応ページ(図4-1で再現)を見ることができます:</p>

<pre><code>http://localhost/frontend_dev.php/content/index
</code></pre>

<p>この章ではデフォルトの<code>index</code>アクションを使わないので、<code>actions.class.php</code>ファイルから<code>executeIndex()</code>メソッドを、<code>templates/</code>ディレクトリから<code>indexSuccess.php</code>ファイルを削除できます。</p>

<blockquote class="note"><p>
  symfonyはコマンドライン以外にもモジュールを初期化するほかの方法を提供します。その1つはあなた自身でディレクトリを作ることです。多くの場合、アクションとモジュールのテンプレートは任意のテーブルのデータを操作するために作られます。テーブルからレコードを作成する、読みとる、更新する、削除するために必要なコードはしばしば同じなので、symfonyはこのコードを生成するためのメカニズムを提供します。このテクニックに関する詳細な情報は14章を参照してください。</p>
</blockquote>

<p>図4-1 - 生成されたデフォルトのindexページ</p>

<p><img src="images/F0401.jpg" alt="生成されたデフォルトのindexページ" title="生成されたデフォルトのindexページ" /></p>

<a name="adding.a.page" id="adding.a.page"></a><h2>ページを追加する</h2>

<p>symfonyにおいて、ページの背後にあるロジックはアクションに保存され、プレゼンテーションはテンプレートに保存されます。ロジックをともなわないページでも空のアクションを必要とします。</p>

<a name="adding.an.action" id="adding.an.action"></a><h3>アクションを追加する</h3>

<p>"Hello, world!"のページは<code>show</code>アクションを通してアクセスできます。リスト4-2で示されているように、このアクションを作るには、<code>contentActions</code>クラスに<code>executeShow</code>メソッドを追加します。</p>

<p>リスト4-2 - アクションを追加するにはアクションクラスに実行メソッドを追加する(<code>actions/actions.class.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw2">class</span> contentActions <span class="kw2">extends</span> sfActions
<span class="br0">&#123;</span>
  <span class="kw2">public</span> <span class="kw2">function</span> executeShow<span class="br0">&#40;</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre>

<p>アクションのメソッド名はつねに<code>executeXxx()</code>で、名前の2番目の部分は大文字で始まるクションの名前です。</p>

<p>では、つぎのURLをリクエストしてください:</p>

<pre><code>http://localhost/frontend_dev.php/content/show
</code></pre>

<p>symfonyが<code>showSuccess.php</code>テンプレートが見つからないことを訴えます。これは正常なことです; symfonyにおいて、ページはつねにアクションとテンプレートで構成されます。</p>

<blockquote class="caution"><p>
  URL(ドメイン名ではありません)と同じように、symfonyは大文字と小文字を区別します(PHPのメソッド名は大文字と小文字を区別しません)。このことはブラウザーで<code>sHow</code>を呼び出すと、symfonyが404エラーを返すことを意味します。</p>
</blockquote>

<p>-</p>

<blockquote class="sidebar"><p class="title">
  URLはレスポンスの一部</p>
  
  <p>symfonyは実際のアクションの名前とアクションを呼び出すために必要なURLの形式を完全に分離できるようにするルーティングシステムを備えています。このメカニズムによってURLをあたかもレスポンスの一部のようにカスタム形式で整えることができます。ファイル構造やリクエストパラメーターによって制限されることはもはやありません; アクション用のURLを望むフレーズで表示できます。たとえば、通常、articleモジュールのindexアクションを呼び出すにはURLはつぎのようになります:</p>

<pre><code>http://localhost/frontend_dev.php/article/index?id=123
</code></pre>
  
  <p>このURLではデータベースから任意の記事をとり出します。この例では、ヨーロッパのセクションのとりわけフランスのファイナンスを議論している記事(<code>id=123</code>)がとり出されます。しかしながら、<code>routing.yml</code>設定ファイルを少し変更することでURLを完全に異なる形式で書けます:</p>

<pre><code>http://localhost/articles/europe/france/finance.html
</code></pre>
  
  <p>検索エンジンにわかりやすいURLになるだけでなく、ユーザーにとっても重要です。ユーザーは、カスタムクエリを行うために、つぎのようにアドレスバーを擬似コマンドラインとして使うことができます:</p>

<pre><code>http://localhost/articles/tagged/finance+france+euro
</code></pre>
  
  <p>symfonyはユーザーのためにスマートURLを解析し生成する方法を知っています。ルーティングシステムはスマートURLからリクエストパラメーターを自動的に読みとり、アクションがこれらを利用できるようにします。レスポンスに含まれるハイパーリンクの形式が整えられるので、これらは"スマート"に見えます。この機能は9章で詳しく学ぶことになります。</p>
  
  <p>全体的に、このことはアプリケーションのアクションを命名する方法は、アクションを呼び出すために使われるURLの見た目ではなく、アプリケーションのアクションの機能によって影響されることを意味します。アクションの名前はアクションが実際に行うことを説明し、不定形の動詞(<code>show</code>、<code>list</code>、<code>edit</code>など)であることがよくあります。アクションの名前は全体的にエンドユーザーには見えないので、明確な名前(<code>listByName</code>もしくは<code>showWithComments</code>など)を使うことをためらわないでください。アクションの機能を説明するコードのコメントを書かずにすむことに加えて、コードがはるかに読みやすくなります。</p>
</blockquote>

<a name="adding.a.template" id="adding.a.template"></a><h3>テンプレートを追加する</h3>

<p>アクションは自分自身をレンダリングすることをテンプレートに要求します。テンプレートはモジュールの<code>templates/</code>ディレクトリに設置されたファイルで、アクションの名前とアクションのサフィックスをつなげて命名されます。アクションのデフォルトの接尾辞は"success"なので、<code>show</code>アクションのために作られるテンプレートファイルは<code>showSuccess.php</code>という名前になります。</p>

<p>テンプレートはプレゼンテーション用のコードだけを含むことを前提としているので、これらをできるかぎり小さなPHPコードとして維持してください。当然のことながら、"Hello, world!"を表示するページはリスト4-3のようなシンプルなテンプレートを持つことができます。</p>

<p>リスト4-3 - テンプレート(<code>content/templates/showSuccess.php</code>)</p>

<pre class="php"><span class="sy0">&lt;</span>p<span class="sy0">&gt;</span>Hello<span class="sy0">,</span> world<span class="sy0">!&lt;/</span>p<span class="sy0">&gt;</span></pre>

<p>テンプレートのなかでPHPコードを実行する必要がある場合、リスト4-4で示すように、通常のPHP構文は避けるべきです。代わりに、PHPプログラマではない人でも理解できるように、リスト4-5で示されるPHPの代替構文を使うテンプレートを書きます。最終的なコードを正しくインデントするだけでなく、アクションの複雑なPHPコードを維持するための助けになります。なぜなら制御文(<code>if</code>、<code>foreach</code>、<code>while</code>など)だけが代替構文を持つからです。</p>

<p>リスト4-4 - アクションにはよいが、テンプレートにはよくない通常のPHP構文(<code>templates/showSuccess.php</code>)</p>

<pre class="php">&lt;p&gt;Hello, world!&lt;/p&gt;
<span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$test</span><span class="br0">&#41;</span>
<span class="br0">&#123;</span>
  <span class="kw1">echo</span> <span class="st0">&quot;&lt;p&gt;&quot;</span><span class="sy0">.</span><span class="kw3">time</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">.</span><span class="st0">&quot;&lt;/p&gt;&quot;</span><span class="sy0">;</span>
<span class="br0">&#125;</span>
&nbsp;
<span class="sy1">?&gt;</span></pre>

<p>リスト4-5 - テンプレート用の代替のPHP構文のよい例(<code>templates/showSuccess.php</code>)</p>

<pre class="php">&lt;p&gt;Hello, world!&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$test</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
  &lt;p&gt;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="kw3">time</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span></pre>

<blockquote class="tip"><p>
  テンプレートの構文が十分に読みやすいものか確認するためのよい経験則はPHPもしくは波かっこでechoされるHTMLコードを含まないことです。また多くの場合、<code>&lt;?php</code>で展開するとき、同じ行の<code>?&gt;</code>で閉じることです。</p>
</blockquote>

<a name="passing.information.from.the.action.to.the.template" id="passing.information.from.the.action.to.the.template"></a><h3>テンプレートにアクションからの情報を渡す</h3>

<p>アクションの仕事はすべての複雑な計算、データのとり出し、とテストの実施、echoもしくはテストされるテンプレートに対して変数を設定することです。symfonyは(アクションの<code>$this-&gt;variableName</code>経由でアクセスされる)アクションクラスのプロパティが(<code>$variableName</code>経由で)グローバルな名前空間内のテンプレートに直接アクセスできるようにします。リスト4-6と4-7はテンプレートにアクションからの情報を渡す方法を示しています。</p>

<p>リスト4-6 - テンプレートがアクションのプロパティを利用できるようにアクションを設定する(<code>content/actions/actions.class.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw2">class</span> contentActions <span class="kw2">extends</span> sfActions
<span class="br0">&#123;</span>
  <span class="kw2">public</span> <span class="kw2">function</span> executeShow<span class="br0">&#40;</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="re0">$today</span> <span class="sy0">=</span> <span class="kw3">getdate</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">hour</span> <span class="sy0">=</span> <span class="re0">$today</span><span class="br0">&#91;</span><span class="st_h">'hours'</span><span class="br0">&#93;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre>

<p>リスト4-7 - テンプレートはアクションのプロパティに直接アクセスできる(<code>templates/showSuccess.php</code>)</p>

<pre class="php">&lt;p&gt;Hello, world!&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$hour</span> <span class="sy0">&gt;=</span> <span class="nu0">18</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
  &lt;p&gt;Or should I say good evening? It is already <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$hour</span> <span class="sy1">?&gt;</span>.&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span></pre>

<p>省略形式の開始タグ(<code>&lt;?=</code>は<code>&lt;?php echo</code>と同じ)の使用はプロフェッショナルなWebアプリケーションでは非推奨であることに注意してください。運用のWebサーバーが複数のスクリプト言語を混同する可能性があるからです。加えて省略形式の開始タグはPHPのデフォルト設定では機能せず、有効にするためにサーバーを調整する必要があるからです(訳注：short_open_tagディレクティブをonに設定する)。結局のところ、XMLとバリデーションを処理しなければならないとき、XMLにおいて<code>&lt;?</code>は特別な意味を持つので不十分な表記です。</p>

<blockquote class="note"><p>
  アクションの変数をセットアップしなくてもデフォルトでテンプレートはデータのごく一部にアクセスできます。すべてのテンプレートは<code>$sf_request</code>, <code>$sf_params</code>、<code>$sf_response</code>、と<code>$sf_user</code>オブジェクトのメソッドを呼び出すことができます。これらのオブジェクトは現在のリクエスト、リクエストパラメーター、セッションに関連するデータを格納します。まもなくこれらを効率的に使う方法を学ぶことになります。</p>
</blockquote>

<a name="linking.to.another.action" id="linking.to.another.action"></a><h2>別のアクションにリンクする</h2>

<p>アクションの名前とそれを呼び出すURLが完全に分離されていることはご存じのとおりです。ですのでリスト4-10のようにテンプレートのなかで<code>update</code>アクションへのリンクを作る場合、リンクはデフォルトのルーティングのみで機能します。URLの表示方法の変更をあとで決める場合、ハイパーリンクを変更するにはすべてのテンプレートを再吟味する必要があります。</p>

<p>リスト4-10 - 古典的なハイパーリンク</p>

<pre class="php"><span class="sy0">&lt;</span>a href<span class="sy0">=</span><span class="st0">&quot;/frontend_dev.php/content/update?name=anonymous&quot;</span><span class="sy0">&gt;</span>
  私の名前は教えません
<span class="sy0">&lt;/</span>a<span class="sy0">&gt;</span></pre>

<p>このやっかいな問題を避けるには、アプリケーションのアクションへのハイパーリンクを作る<code>link_to</code>ヘルパーをつねに使うべきです。そしてURLの部分を生成したい場合、<code>url_for()</code>が求めるヘルパーです。</p>

<p>ヘルパー(helper)とはsymfonyで定義されたテンプレートのなかでHTMLコードを出力するPHP関数です。HTMLコードを直接書くよりこれを使うほうが速く書けます。リスト4-11はハイパーリンクヘルパーの使いかたを示しています。</p>

<p>リスト4-11 - <code>link_to()</code>と<code>url_for()</code>ヘルパー(<code>templates/***Success.php</code>)</p>

<pre class="php">&lt;p&gt;こんにちは！&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$hour</span> <span class="sy0">&gt;=</span> <span class="nu0">18</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
&lt;p&gt;もしくはこんばんはと言ったほうがよろしいでしょうか？現在<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$hour</span> <span class="sy1">?&gt;</span>時です。&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span>
&lt;form method=&quot;post&quot; action=&quot;<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> url_for<span class="br0">&#40;</span><span class="st_h">'content/update'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>&quot;&gt;
  &lt;label for=&quot;name&quot;&gt;お名前は？&lt;/label&gt;
  &lt;input type=&quot;text&quot; name=&quot;name&quot; id=&quot;name&quot; value=&quot;&quot; /&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Ok&quot; /&gt;
  <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> link_to<span class="br0">&#40;</span><span class="st_h">'名前を教えない'</span><span class="sy0">,</span><span class="st_h">'content/update?name=anonymous'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&lt;/form&gt;</pre>

<p>ルーティングルールを変更しても、すべてのテンプレートは正しくふるまい、ルールにしたがってURLを再び整形すること以外結果のHTMLは以前のものと同じになります。</p>

<p>symfonyはフォームの操作をずっと簡単になるツールをたくさん提供するので、フォームの操作はそれだけで1つの章の説明をする必要があります。10章でこれらのヘルパーについて詳細な内容を学ぶことになります。</p>

<p><code>link_to()</code>ヘルパーは、多くのヘルパーと同じように、特別なオプションと追加のタグ属性用の別の引数を受けとります。リスト4-12はオプション引数の例と結果のHTMLを示しています。オプション引数は連想配列もしくは空白文字で区切られた<code>key=value</code>の組を表示するシンプルな文字列です。</p>

<p>リスト4-12 - たいていのヘルパーはオプション引数を受けとる(<code>templates/***Success.php</code>)</p>

<pre class="php">// 連想配列としてのオプション引数
<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> link_to<span class="br0">&#40;</span><span class="st_h">'名前を教えない'</span><span class="sy0">,</span> <span class="st_h">'content/update?name=anonymous'</span><span class="sy0">,</span>
  <span class="kw3">array</span><span class="br0">&#40;</span>
    <span class="st_h">'class'</span>    <span class="sy0">=&gt;</span> <span class="st_h">'special_link'</span><span class="sy0">,</span>
    <span class="st_h">'confirm'</span>  <span class="sy0">=&gt;</span> <span class="st_h">'よろしいですか？'</span><span class="sy0">,</span>
    <span class="st_h">'absolute'</span> <span class="sy0">=&gt;</span> <span class="kw4">true</span>
<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&nbsp;
// 文字列としてのオプション引数
<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> link_to<span class="br0">&#40;</span><span class="st_h">'名前を教えない'</span><span class="sy0">,</span> <span class="st_h">'content/update?name=anonymous'</span><span class="sy0">,</span>
  <span class="st_h">'class=special_link confirm=Are you sure? absolute=true'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>
&nbsp;
// 両方の呼び出しは同じものを出力する
 =&gt; &lt;a class=&quot;special_link&quot; onclick=&quot;return confirm('Are you sure?');&quot;
    href=&quot;http://localhost/frontend_dev.php/content/update/name/anonymous&quot;&gt;
    名前を教えない&lt;/a&gt;</pre>

<p>HTMLタグを出力するsymfonyのヘルパーを使うとき、オプション引数に(リスト4-12の例の<code>class</code>属性のような)追加のタグ属性を挿入できます。これらの属性を"速くて汚い"HTML 4.0の方法(ダブルクォートなし)で書くこともできますが、symfonyはこれらをすばらしく整形されたXHTMLの形式で出力します。それがHTMLよりもヘルパーを速く書ける別の理由です。</p>

<blockquote class="note"><p>
  追加の解析と変換が必要なので、文字列の構文は配列よりも若干遅いです。</p>
</blockquote>

<p>symfonyのすべてのヘルパーのように、リンクヘルパーとオプションは数多く存在します。9章でこれらを詳しく説明します。</p>

<a name="getting.information.from.the.request" id="getting.information.from.the.request"></a><h2>リクエストから情報を入手する</h2>

<p>ユーザーが送信した情報がフォーム経由(通常はPOSTリクエスト)もしくはURL経由(GETリクエスト)のどちらでも、<code>sfRequest</code>オブジェクトの<code>getParameter()</code>メソッドを使用してアクションから関連データをとり出すことができます。リスト4-13は、<code>update</code>メソッドで<code>name</code>パラメーターの値をとり出す方法を示しています。</p>

<p>リスト4-13 - データをアクションのリクエストパラメーターから取得する(<code>content/actions/actions.class.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span>
&nbsp;
<span class="kw2">class</span> contentActions <span class="kw2">extends</span> sfActions
<span class="br0">&#123;</span>
  <span class="co1">// ...</span>
&nbsp;
  <span class="kw2">public</span> <span class="kw2">function</span> executeUpdate<span class="br0">&#40;</span><span class="re0">$request</span><span class="br0">&#41;</span>
  <span class="br0">&#123;</span>
    <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">name</span> <span class="sy0">=</span> <span class="re0">$request</span><span class="sy0">-&gt;</span><span class="me1">getParameter</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span><span class="sy0">;</span>
  <span class="br0">&#125;</span>
<span class="br0">&#125;</span></pre>

<p>利便性に関して、すべての<code>executeXxx()</code>メソッドは最初の引数として現在の<code>sfRequest</code>オブジェクトを受けとります。</p>

<p>データの操作がシンプルであるなら、リクエストパラメーターをとり出すためにアクションを使う必要もありません。テンプレートが<code>$sf_params</code>オブジェクトにアクセスできるからです。アクションの<code>getParameter()</code>と同様に、<code>$sf_params</code>はリクエストパラメーターをとり出す<code>get()</code>メソッドを提供します。</p>

<p><code>executeUpdate()</code>が空の場合、リスト4-14は<code>updateSuccess.php</code>テンプレートが同じ<code>name</code>パラメーターをとり出す方法を示しています。</p>

<p>リスト4-14 - リクエストパラメーターをテンプレートから直接取得する(<code>templates/***Success.php</code>)</p>

<pre class="php">&lt;p&gt;Hello, <span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$sf_params</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>!&lt;/p&gt;</pre>

<blockquote class="note"><p>
  代わりに<code>$_POST</code>、<code>$_GET</code>、<code>$_REQUEST</code>変数を使わないのはなぜでしょうか？URLは異なるようにフォーマットされるため(たとえば<code>?</code>や<code>=</code>をともなわない<code>http://localhost/articles/europe/france/finance.html</code>)、通常のPHP変数はそれ以上機能しないので、ルーティングシステムのみがリクエストパラメーターをとり出すことができるからです。悪意のあるコードのインジェクションを防止するために入力フィルタリングを追加したい場合、すべてのリクエストパラメーターを1つのクリーンなパラメーターホルダーに格納することで実現できます。</p>
</blockquote>

<p><code>$sf_params</code>オブジェクトは配列に同等のゲッターを単に渡すよりも強力です。たとえば、リクエストパラメーターの存在を確認したい場合、リスト4-15のように、<code>get()</code>で実際の値を試す代わりに<code>$sf_params-&gt;has()</code>メソッドが簡単に使えます。</p>

<p>リスト4-15 - テンプレートのなかでリクエストパラメーターを試す(<code>templates/***Success.php</code>)</p>

<pre class="php"><span class="kw2">&lt;?php</span> <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re0">$sf_params</span><span class="sy0">-&gt;</span><span class="me1">has</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
  &lt;p&gt;こんにちは、<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$sf_params</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>さん！&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">else</span><span class="sy0">:</span> <span class="sy1">?&gt;</span>
  &lt;p&gt;こんにちは、John Doeさん！&lt;/p&gt;
<span class="kw2">&lt;?php</span> <span class="kw1">endif</span><span class="sy0">;</span> <span class="sy1">?&gt;</span></pre>

<p>読者のなかにはこれを一行で書けることを推測している人がいることでしょう。symfonyのたいていのゲッターメソッドに関しては、アクションの<code>$request-&gt;getParameter()</code>メソッドとテンプレートの<code>$sf_params-&gt;get()</code>メソッド(実際には、同じオブジェクトの同じメソッドの呼び出し)の両方とも2番目の引数としてリクエストパラメーターが存在しない場合に使われるデフォルト値を受けとります。</p>

<pre class="php">&lt;p&gt;こんにちは、<span class="kw2">&lt;?php</span> <span class="kw1">echo</span> <span class="re0">$sf_params</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="st_h">'name'</span><span class="sy0">,</span> <span class="st_h">'John Doe'</span><span class="br0">&#41;</span> <span class="sy1">?&gt;</span>さん！&lt;/p&gt;</pre>

<a name="summary" id="summary"></a><h2>まとめ</h2>

<p>symfonyにおいて、ページはアクション(action)とテンプレート(template)で構成されます。アクションは<code>actions/actions.class.php</code>ファイルのメソッドでプレフィックスは<code>execute</code>です。テンプレートは<code>templates/</code>ディレクトリのなかのファイルで、通常は<code>Success.php</code>で終わります。これらはアプリケーションの機能にしたがって、モジュール(module)に分類されます。ヘルパーによってテンプレートを書く作業が円滑になります。ヘルパー(helper)とはsymfonyによって提供されるHTMLコードを返す関数です。そして、必要に応じて整形されるURLはレスポンスの一部として考えることが必要です。ですのでアクションの命名もしくはリクエストパラメーターの読みとりにおいてURLを直接参照することは避けるべきです。</p>

<p>これらの基本原則を理解したら、すでにアプリケーション全体を書けます。しかしこれだけでは作業が長すぎます。アプリケーションの開発過程で成し遂げなければならないほとんどすべてのタスクはsymfonyの別の機能によって1つもしくは別の方法で円滑に行われます・・・今のところこの本が終わらない理由です。</p>
</div>
<div class="navigation">
<hr/>
<table width="100%">
<tr>
<td width="40%" align="left"><a href="03-Running-Symfony.html">前の章</a></td>
<td width="20%" align="center"><a href="index.html">ホーム</a></td>
<td width="40%" align="right"><a href="05-Configuring-Symfony.html">次の章</a></td>
</tr>
</table>

</div>
</body>

</html>
